include( "shared.lua" )

ENT.Material = Material("effects/tool_tracer")

function ENT:Draw()
end

function ENT:Initialize()
	self.On = false
	
	if(!self.Cams) then
		self.Cams = {}
	end
	
	self.Index = 1
	
	if(!self.StepDuration) then
		self.StepDuration = 4
	end
end

function ENT:AddCamera(CamEnt, Index)
	self.Cams[Index] = CamEnt
end

function ENT:CheckPoints()
	local NewCams = {}
	
	for i, v in pairs(self.Cams) do
		if(v && v:IsValid()) then
			table.insert(NewCams, v)
		end
	end
	
	self.Cams = NewCams
end

function ENT:Start(CamEnt)
	Msg("Starting\n")
	self.On = true
	self.StartTime = CurTime()
	self.CamEnt = CamEnt
end

function ENT:Stop()
	self.On = false
end

/*
_____           _     __         __         __  ______
|  _ \         / \    \ \       /  \       / /  |   _ \
| | | |       / _ \    \ \     / /\ \     / /   | | | |
| |_| |      / / \ \    \ \   / /  \ \   / /    | |_| |
|  _ /      / /___\ \    \ \ / /    \ \ / /     |  _  /
| | \ \    / _______ \    \ V /      \ V /      | | \ \
|_|  \_\  / /       \ \    \_/        \_/       |_|  \_\

*/

function GetPos(Position, Length, Start, Middle, End)
	local Pos = Position/Length
	local PosTrig = Pos*(math.pi/2)
	
	local Difference = Middle - Start
	local Difference2 = End - Middle
	
	local Sin = math.sin(PosTrig)-1
	local Cos = math.cos(PosTrig)
	
	local X = End.x-((Difference2.x*Cos)-(Difference.x*Sin))
	local Y = End.y-((Difference2.y*Cos)-(Difference.y*Sin))
	local Z = End.z-((Difference2.z*Cos)-(Difference.z*Sin))
	
	local Return = Vector(X, Y, Z)
	
	return Return
end

function GetAng(Position, Length, Start, Middle, End)
	local Pos = Position/Length
	local PosTrig = Pos*(math.pi/2)
	
	local Dif = Middle - Start
	local Dif2 = End - Middle
	
	Dif1P = math.AngleDifference(Middle.p, Start.p)
	Dif2P = math.AngleDifference(End.p, Middle.p)
	Dif1Y = math.AngleDifference(Middle.y, Start.y)
	Dif2Y = math.AngleDifference(End.y, Middle.y)
	Dif1R = math.AngleDifference(Middle.r, Start.r)
	Dif2R = math.AngleDifference(End.r, Middle.r)
	
	local Sin = math.sin(PosTrig)-1
	local Cos = math.cos(PosTrig)
	
	local P = End.p-((Dif2P*Cos)-(Dif1P*Sin))
	local Y = End.y-((Dif2Y*Cos)-(Dif1Y*Sin))
	local R = End.r-((Dif2R*Cos)-(Dif1R*Sin))
	
	local Return = Angle(P, Y, R)
	
	return Return
end

function ENT:Think()
	if(!self.On) then
		return
	end
	
	if(!self.Cams) then
		self:Stop()
		return
	end
	
	if(!self.Cams[2]) then
		self:Stop()
		return
	end
	
	Index = self.Index
	StepDuration = self.StepDuration / table.Count(self.Cams)
	Positions = {}
	Angles = {}
	
	Positions[0] = self.Cams[Index]:GetPos()
	Angles[0] = self.Cams[Index]:GetAngles()
	Positions[1] = self.Cams[Index + 1]:GetPos()
	Angles[1] = self.Cams[Index + 1]:GetAngles()
	Positions[2] = self.Cams[Index + 2]:GetPos()
	Angles[2] = self.Cams[Index + 2]:GetAngles()
	
	MidPos = {}
	MidAng = {}
	
	MidPos[0] = (Positions[0] + Positions[1]) / 2
	MidPos[1] = (Positions[1] + Positions[2]) / 2
	
	MidAng[0] = (Angles[0] + Angles[1])
	MidAng[1] = (Angles[1] + Angles[2])
	
	for i, v in pairs(MidAng) do
		v.p = v.p / 2
		v.y = v.y / 2
		v.r = v.r / 2
	end
	
	if(Index == 1) then
		MidPos[0] = Positions[0]
		MidAng[0] = Angles[0]
	end
	if(Index == table.Count(self.Cams) - 2) then
		MidPos[1] = Positions[2]
		MidAng[1] = Angles[2]
	end
	
	local Pos = GetPos(CurTime() - self.StartTime, StepDuration, MidPos[0], Positions[1], MidPos[1])
	local Ang = GetAng(CurTime() - self.StartTime, StepDuration, MidAng[0], Angles[1], MidAng[1])
	
	self.CamEnt:SetPos(Pos)
	self.CamEnt:SetAngles(Ang)
	
	if((CurTime() - self.StartTime) >= StepDuration) then
		self.Index = self.Index + 1
		self.StartTime = CurTime()
		if(self.Index > (table.Count(self.Cams) - 2)) then
			self.Index = 1
		end
	end
	
	self:NextThink(CurTime())
	return true
end
